package com.daigoudao.util;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.MemoryCacheImageInputStream;
import javax.swing.ImageIcon;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.imageio.plugins.bmp.BMPImageReader;
import com.sun.imageio.plugins.gif.GIFImageReader;
import com.sun.imageio.plugins.jpeg.JPEGImageReader;
import com.sun.imageio.plugins.png.PNGImageReader;

public class ImageUtil {

	public static final String JPEG = "jpeg";
	public static final String BMP = "bmp";
	public static final String PNG = "png";
	public static final String GIF = "gif";

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		int[] ss = { 50, 120, 200, 300 };
		resize("E:\\javaws\\javaimage\\4.jpg", ss);
	}
	
	public static boolean resize120(String filePath) throws IOException{
		int[] sizes = {120};
		return resize(filePath,sizes);
	}
	
	public static boolean resize50(String filePath) throws IOException{
		int[] sizes = {50};
		return resize(filePath,sizes);
	}
	
	public static boolean resize200(String filePath) throws IOException{
		int[] sizes = {200};
		return resize(filePath,sizes);
	}
	
	public static boolean resize300(String filePath) throws IOException{
		int[] sizes = {300};
		return resize(filePath,sizes);
	}

	public static boolean resize(String filePath, int[] reSizes)
			throws IOException {
		String fileType = getImageType(filePath);
		if (JPEG.equalsIgnoreCase(fileType) || PNG.equalsIgnoreCase(fileType)) {
			int index = filePath.lastIndexOf(".");
			String extName = filePath.substring(index + 1);
			for (int size : reSizes) {
				StringBuilder sb = new StringBuilder(filePath.substring(0,
						index));
				sb.append("_").append(size).append(".").append(extName);
				resize(new File(filePath), new File(sb.toString()), size, 1.0f);
			}
			return true;
		}
		return false;
	}

	/**
	 * 获取缩放后图片的路径
	 * 
	 * @param filePath
	 * @param size
	 * @return
	 */
	public static String getImageFileName(String filePath, int size) {
		int index = filePath.lastIndexOf(".");
		String extName = filePath.substring(index + 1);
		StringBuilder sb = new StringBuilder(filePath.substring(0, index));
		sb.append("_").append(size).append(".").append(extName);
		return sb.toString();
	}

	/**
	 * 图片缩放
	 * 
	 * @param originalFile
	 *            源文件
	 * @param resizedFile
	 *            目标文件
	 * @param newWidth
	 *            新图片的宽度
	 * @param quality
	 *            成像质量
	 * @throws IOException
	 */
	public static void resize(File originalFile, File resizedFile,
			int newWidth, float quality) throws IOException {
		if (quality > 1) {
			throw new IllegalArgumentException(
					"Quality has to be between 0 and 1");
		}

		ImageIcon ii = new ImageIcon(originalFile.getCanonicalPath());
		Image i = ii.getImage();
		Image resizedImage = null;

		int iWidth = i.getWidth(null);
		int iHeight = i.getHeight(null);

		if (iWidth > iHeight) {
			resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight)
					/ iWidth, Image.SCALE_AREA_AVERAGING);
		} else {
			resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight,
					newWidth, Image.SCALE_AREA_AVERAGING);
		}
		// This code ensures that all the pixels in the image are loaded.
		Image temp = new ImageIcon(resizedImage).getImage();

		// Create the buffered image.
		BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null),
		temp.getHeight(null), BufferedImage.TYPE_INT_RGB);
		// Copy image to buffered image.
		Graphics g = bufferedImage.createGraphics();
		// Clear background and paint the image.
		g.setColor(Color.white);
		g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
		g.drawImage(temp, 0, 0, null);
		g.dispose();

		// Soften.
		float softenFactor = 0.05f;
		float[] softenArray = { 0, softenFactor, 0, softenFactor,
				1 - (softenFactor * 4), softenFactor, 0, softenFactor, 0 };
		Kernel kernel = new Kernel(3, 3, softenArray);
		ConvolveOp cOp = new ConvolveOp(kernel,

		ConvolveOp.EDGE_NO_OP, null);
		bufferedImage = cOp.filter(bufferedImage, null);
		// Write the jpeg to a file.
		FileOutputStream out = new FileOutputStream(resizedFile);
		// Encodes image as a JPEG data stream
		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
		JPEGEncodeParam param = encoder
				.getDefaultJPEGEncodeParam(bufferedImage);
		param.setQuality(quality, true);
		encoder.setJPEGEncodeParam(param);
		encoder.encode(bufferedImage);
	}

	/**
	 * 获取文件类型
	 * 
	 * @param filePath
	 * @return
	 * @throws IOException
	 */
	public static String getImageType(String filePath) throws IOException {
		FileInputStream fis = new FileInputStream(filePath);

		int leng = fis.available();
		BufferedInputStream buff = new BufferedInputStream(fis);
		byte[] mapObj = new byte[leng];
		buff.read(mapObj, 0, leng);

		String type = "";
		ByteArrayInputStream bais = null;
		MemoryCacheImageInputStream mcis = null;
		try {
			bais = new ByteArrayInputStream(mapObj);
			mcis = new MemoryCacheImageInputStream(bais);
			Iterator<ImageReader> itr = ImageIO.getImageReaders(mcis);
			while (itr.hasNext()) {
				ImageReader reader = (ImageReader) itr.next();
				if (reader instanceof GIFImageReader) {
					type = GIF;
				} else if (reader instanceof JPEGImageReader) {
					type = JPEG;
				} else if (reader instanceof PNGImageReader) {
					type = PNG;
				} else if (reader instanceof BMPImageReader) {
					type = BMP;
				}
			}
		} finally {
			if (bais != null) {
				try {
					bais.close();
				} catch (IOException ioe) {

				}
			}
			if (mcis != null) {
				try {
					mcis.close();
				} catch (IOException ioe) {

				}
			}
		}
		return type;
	}

}